package com.health.trans.annotation;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.CharUtil;
import cn.hutool.core.util.StrUtil;
import com.health.trans.pojo.FieldInfo;
import com.health.trans.pojo.TableInfo;
import com.health.trans.util.EntityOperations;
import com.health.trans.util.DataSourceUtil;
import lombok.extern.slf4j.Slf4j;

import javax.persistence.Column;
import javax.persistence.Table;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @author nqlz
 */
@Slf4j
public class FieldHandler extends BaseHandler implements ConstraintValidator<FieldValid, TableInfo<?>> {
    @Override
    public void initialize(FieldValid constraintAnnotation) {
    }

    @Override
    public boolean isValid(TableInfo<?> value, ConstraintValidatorContext context) {
        //禁用默认的message的值
        //context.disableDefaultConstraintViolation();
       /* String readTableName = value.getReadTableName();
        if (StrUtil.isBlank(readTableName)) {
            return errMsg("读表不能为空。。", context);
        }
        Class<?> readTableClass = EntityOperations.getPojoClass(value.getReadTableName());
        Class<?> writeTableClass = EntityOperations.getPojoClass(StrUtil.isBlank(value.getWriteTableName()) ? "" : value.getWriteTableName());
        value.setReadTableClass(readTableClass);
        value.setWriteTableClass(writeTableClass);
        //任何情况，读写表不能为空
        if (writeTableClass == null) {
           return errMsg( "写表映射没有对应的实体类",context);
        }
        String tableName = StrUtil.contains(value.getReadTableName(), CharUtil.UNDERLINE) ? value.getReadTableName() : StrUtil.toUnderlineCase(value.getReadTableName());
        //校验优化时间规则
        if (value.isOptimized()) {
            String optimizedFieldName = value.getOptimizedFieldName();
            String dbFileName = StrUtil.contains(optimizedFieldName, CharUtil.UNDERLINE) ? optimizedFieldName : StrUtil.toUnderlineCase(optimizedFieldName);
            String catalog = null;
            if (Objects.nonNull(readTableClass)) {
                Table table = readTableClass.getAnnotation(Table.class);
                catalog = StrUtil.isBlank(table.catalog()) ? null : table.catalog();
                tableName = table.name();
            }
            boolean exist = DataSourceUtil.checkColumnNameExist(value.getReadResource(), catalog, tableName, dbFileName);
            if (!exist) {
                return errMsg("查询时间优化开启，优化字段名有误。", context);
            }
        }

        try {
            if (CollUtil.isNotEmpty(value.getFieldInfos())) {
                //没有读表对应类时的条件字段校验
                if (Objects.isNull(readTableClass)) {
                    List<String> columnNames = value.getFieldInfos().stream().map(FieldInfo::getDbName).collect(Collectors.toList());
                    boolean pass = DataSourceUtil.checkColumnNameExist(value.getReadResource(), null, tableName, columnNames);
                    if (!pass) {
                        return errMsg(columnNames + "有错误字段。", context);
                    }
                }
                //有类时的字段校验
                else {
                    List<Field> fieldNames = Arrays.asList(readTableClass.getDeclaredFields());

                    value.getFieldInfos().parallelStream().forEach(i -> {
                        List<String> keys = Arrays.asList(i.getName(), StrUtil.toCamelCase(i.getName()));
                        Optional<Field> first = fieldNames.stream()
                                .filter(j -> keys.contains(j.getName()))
                                .findFirst();
                        if (!first.isPresent()) {
                            throwException(context, readTableName + " 表 没有该字段:" + i.getName());
                        }
                        if (!i.dateTimeAllNotNull() && i.getValue() == null) {
                            throwException(context, readTableName + " 字段值不能为空 " + i.getName());
                        }
                        Column column = first.get().getAnnotation(Column.class);
                        String name = first.get().getName();
                        i.setDbName(Objects.nonNull(column) ? column.name() : name)
                                .setType(first.get().getType());
                    });
                }*/
            //}
        //} catch (Exception e) {
        //    return false;
        //}
        return true;
    }
}
